//
//  Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
//  Use of this source code is subject to the terms of the Microsoft end-user
//  license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
//  If you did not accept the terms of the EULA, you are not authorized to use
//  this source code. For a copy of the EULA, please see the LICENSE.RTF on your
//  install media.
//
// Portions Copyright (c) MiTAC Corp. All rights reserved.
//------------------------------------------------------------------------------
//
//  File:  lcdterm.c
//  Programmer: Visual.Wei
//  Date: 2007-3-28
//
//  Provide simple terminal like debug output on LCD graphics frame buffer
//  
//

#include <windows.h>
#include <bsp.h>
#include <bsp_oaldisp.h>
#include <bsp_oalkeys.h>

#define DIB_HEADER_MARKER           ((WORD) ('M' << 8) | 'B')

// output color

static UINT16 g_wForeColor = 0xFFFF;
static UINT16 g_wBackColor = 0x0000;

// terminal definitions

static const int ScrWidth = CX_SCREEN;
static const int ScrHeight = CY_SCREEN;
static const int ScrStride = SCR_STRIDE;
static const int TermWidth = TERM_WIDTH;
static const int TermHeight = TERM_HEIGHT;
static const int ScrStatusHeight = CY_STATUS_HEIGHT;

static int CursorX = 0, CursorY = 0;
static UINT16 g_wCharAttribute = DISP_ATTR_NORMAL;

// screen base address

static PWORD pScreen;
static PWORD pwFrame;
static BOOL g_bLineWrap = TRUE;

//------------------------------------------------------------------------------
//
//  Courier 10pt font data
//

static UINT8 fontdata[] = {
                              /*  30 */ 0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00,
                              /*  31 */ 0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00,
                              /*  32 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                              /*  33 */ 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
                              /*  34 */ 0x00, 0x00, 0x00, 0x36, 0x36, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                              /*  35 */ 0x00, 0x00, 0x12, 0x12, 0x24, 0x7e, 0x24, 0x24, 0x7e, 0x24, 0x48, 0x48, 0x00, 0x00,
                              /*  36 */ 0x00, 0x00, 0x08, 0x1c, 0x24, 0x20, 0x18, 0x04, 0x24, 0x38, 0x08, 0x08, 0x00, 0x00,
                              /*  37 */ 0x00, 0x00, 0x00, 0x20, 0x50, 0x20, 0x0c, 0x70, 0x08, 0x14, 0x08, 0x00, 0x00, 0x00,
                              /*  38 */ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x10, 0x18, 0x2a, 0x24, 0x1e, 0x00, 0x00, 0x00,
                              /*  39 */ 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                              /*  40 */ 0x00, 0x00, 0x00, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x00,
                              /*  41 */ 0x00, 0x00, 0x00, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x00,
                              /*  42 */ 0x00, 0x00, 0x00, 0x08, 0x3e, 0x08, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                              /*  43 */ 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
                              /*  44 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x30, 0x20, 0x00,
                              /*  45 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                              /*  46 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
                              /*  47 */ 0x00, 0x00, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x00, 0x00,
                              /*  48 */ 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00,
                              /*  49 */ 0x00, 0x00, 0x00, 0x08, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00,
                              /*  50 */ 0x00, 0x00, 0x00, 0x38, 0x44, 0x04, 0x08, 0x10, 0x20, 0x44, 0x7c, 0x00, 0x00, 0x00,
                              /*  51 */ 0x00, 0x00, 0x00, 0x38, 0x44, 0x04, 0x18, 0x04, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00,
                              /*  52 */ 0x00, 0x00, 0x00, 0x0c, 0x14, 0x24, 0x24, 0x7e, 0x04, 0x04, 0x0e, 0x00, 0x00, 0x00,
                              /*  53 */ 0x00, 0x00, 0x00, 0x3e, 0x20, 0x20, 0x3c, 0x02, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00,
                              /*  54 */ 0x00, 0x00, 0x00, 0x0e, 0x10, 0x20, 0x3c, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00,
                              /*  55 */ 0x00, 0x00, 0x00, 0x7e, 0x42, 0x02, 0x04, 0x04, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
                              /*  56 */ 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00,
                              /*  57 */ 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x04, 0x78, 0x00, 0x00, 0x00,
                              /*  58 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
                              /*  59 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x30, 0x20, 0x00, 0x00,
                              /*  60 */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x10, 0x60, 0x10, 0x0c, 0x02, 0x00, 0x00, 0x00,
                              /*  61 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                              /*  62 */ 0x00, 0x00, 0x00, 0x00, 0x40, 0x30, 0x08, 0x06, 0x08, 0x30, 0x40, 0x00, 0x00, 0x00,
                              /*  63 */ 0x00, 0x00, 0x00, 0x1c, 0x22, 0x02, 0x02, 0x04, 0x08, 0x00, 0x18, 0x00, 0x00, 0x00,
                              /*  64 */ 0x00, 0x00, 0x38, 0x44, 0x44, 0x4c, 0x54, 0x54, 0x4c, 0x40, 0x44, 0x38, 0x00, 0x00,
                              /*  65 */ 0x00, 0x00, 0x00, 0x18, 0x08, 0x14, 0x14, 0x14, 0x1c, 0x22, 0x77, 0x00, 0x00, 0x00,
                              /*  66 */ 0x00, 0x00, 0x00, 0x7c, 0x22, 0x22, 0x3c, 0x22, 0x22, 0x22, 0x7c, 0x00, 0x00, 0x00,
                              /*  67 */ 0x00, 0x00, 0x00, 0x1e, 0x22, 0x40, 0x40, 0x40, 0x40, 0x22, 0x1c, 0x00, 0x00, 0x00,
                              /*  68 */ 0x00, 0x00, 0x00, 0x78, 0x24, 0x22, 0x22, 0x22, 0x22, 0x24, 0x78, 0x00, 0x00, 0x00,
                              /*  69 */ 0x00, 0x00, 0x00, 0x7e, 0x22, 0x28, 0x38, 0x28, 0x20, 0x22, 0x7e, 0x00, 0x00, 0x00,
                              /*  70 */ 0x00, 0x00, 0x00, 0x7e, 0x22, 0x28, 0x38, 0x28, 0x20, 0x20, 0x70, 0x00, 0x00, 0x00,
                              /*  71 */ 0x00, 0x00, 0x00, 0x1e, 0x22, 0x40, 0x40, 0x47, 0x42, 0x22, 0x1c, 0x00, 0x00, 0x00,
                              /*  72 */ 0x00, 0x00, 0x00, 0x77, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x77, 0x00, 0x00, 0x00,
                              /*  73 */ 0x00, 0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00,
                              /*  74 */ 0x00, 0x00, 0x00, 0x1e, 0x04, 0x04, 0x04, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00,
                              /*  75 */ 0x00, 0x00, 0x00, 0x77, 0x22, 0x24, 0x28, 0x38, 0x24, 0x22, 0x73, 0x00, 0x00, 0x00,
                              /*  76 */ 0x00, 0x00, 0x00, 0x70, 0x20, 0x20, 0x20, 0x20, 0x22, 0x22, 0x7e, 0x00, 0x00, 0x00,
                              /*  77 */ 0x00, 0x00, 0x00, 0x77, 0x36, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x77, 0x00, 0x00, 0x00,
                              /*  78 */ 0x00, 0x00, 0x00, 0xe7, 0x62, 0x52, 0x52, 0x4a, 0x4a, 0x46, 0xe6, 0x00, 0x00, 0x00,
                              /*  79 */ 0x00, 0x00, 0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x00,
                              /*  80 */ 0x00, 0x00, 0x00, 0x7c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x70, 0x00, 0x00, 0x00,
                              /*  81 */ 0x00, 0x00, 0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x1f, 0x00, 0x00,
                              /*  82 */ 0x00, 0x00, 0x00, 0x7c, 0x22, 0x22, 0x22, 0x3c, 0x24, 0x22, 0x71, 0x00, 0x00, 0x00,
                              /*  83 */ 0x00, 0x00, 0x00, 0x3a, 0x46, 0x40, 0x3c, 0x02, 0x02, 0x62, 0x5c, 0x00, 0x00, 0x00,
                              /*  84 */ 0x00, 0x00, 0x00, 0x7f, 0x49, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00,
                              /*  85 */ 0x00, 0x00, 0x00, 0x77, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00,
                              /*  86 */ 0x00, 0x00, 0x00, 0xe7, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00, 0x00,
                              /*  87 */ 0x00, 0x00, 0x00, 0x77, 0x22, 0x22, 0x2a, 0x2a, 0x2a, 0x2a, 0x14, 0x00, 0x00, 0x00,
                              /*  88 */ 0x00, 0x00, 0x00, 0x77, 0x22, 0x14, 0x08, 0x08, 0x14, 0x22, 0x77, 0x00, 0x00, 0x00,
                              /*  89 */ 0x00, 0x00, 0x00, 0x77, 0x22, 0x14, 0x14, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00,
                              /*  90 */ 0x00, 0x00, 0x00, 0x3e, 0x22, 0x04, 0x08, 0x08, 0x10, 0x22, 0x3e, 0x00, 0x00, 0x00,
                              /*  91 */ 0x00, 0x00, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1c, 0x00,
                              /*  92 */ 0x00, 0x00, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x00, 0x00,
                              /*  93 */ 0x00, 0x00, 0x00, 0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x00,
                              /*  94 */ 0x00, 0x00, 0x10, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                              /*  95 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
                              /*  96 */ 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                              /*  97 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x3e, 0x42, 0x46, 0x3b, 0x00, 0x00, 0x00,
                              /*  98 */ 0x00, 0x00, 0x00, 0xc0, 0x40, 0x5c, 0x62, 0x42, 0x42, 0x62, 0xdc, 0x00, 0x00, 0x00,
                              /*  99 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x46, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00,
                              /* 100 */ 0x00, 0x00, 0x00, 0x06, 0x02, 0x3a, 0x46, 0x42, 0x42, 0x46, 0x3b, 0x00, 0x00, 0x00,
                              /* 101 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x7e, 0x40, 0x40, 0x3e, 0x00, 0x00, 0x00,
                              /* 102 */ 0x00, 0x00, 0x00, 0x0e, 0x10, 0x7e, 0x10, 0x10, 0x10, 0x10, 0x7e, 0x00, 0x00, 0x00,
                              /* 103 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x46, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x3c, 0x00,
                              /* 104 */ 0x00, 0x00, 0x00, 0x60, 0x20, 0x2c, 0x32, 0x22, 0x22, 0x22, 0x77, 0x00, 0x00, 0x00,
                              /* 105 */ 0x00, 0x00, 0x00, 0x08, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00,
                              /* 106 */ 0x00, 0x00, 0x00, 0x08, 0x00, 0x3c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x78, 0x00,
                              /* 107 */ 0x00, 0x00, 0x00, 0x60, 0x20, 0x2f, 0x24, 0x38, 0x28, 0x24, 0x67, 0x00, 0x00, 0x00,
                              /* 108 */ 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00,
                              /* 109 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0x6d, 0x49, 0x49, 0x49, 0xed, 0x00, 0x00, 0x00,
                              /* 110 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x32, 0x22, 0x22, 0x22, 0x77, 0x00, 0x00, 0x00,
                              /* 111 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00,
                              /* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x32, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x70, 0x00,
                              /* 113 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x46, 0x42, 0x42, 0x46, 0x3a, 0x02, 0x07, 0x00,
                              /* 114 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x30, 0x20, 0x20, 0x20, 0x7c, 0x00, 0x00, 0x00,
                              /* 115 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x42, 0x3c, 0x02, 0x42, 0x7c, 0x00, 0x00, 0x00,
                              /* 116 */ 0x00, 0x00, 0x00, 0x00, 0x20, 0x7c, 0x20, 0x20, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00,
                              /* 117 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x22, 0x22, 0x22, 0x26, 0x1b, 0x00, 0x00, 0x00,
                              /* 118 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x42, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00, 0x00,
                              /* 119 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x22, 0x2a, 0x2a, 0x2a, 0x14, 0x00, 0x00, 0x00,
                              /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x24, 0x18, 0x18, 0x24, 0x66, 0x00, 0x00, 0x00,
                              /* 121 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x38, 0x00,
                              /* 122 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x24, 0x08, 0x10, 0x22, 0x3e, 0x00, 0x00, 0x00,
                              /* 123 */ 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x10, 0x20, 0x10, 0x10, 0x10, 0x08, 0x00, 0x00,
                              /* 124 */ 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00,
                              /* 125 */ 0x00, 0x00, 0x00, 0x20, 0x10, 0x10, 0x10, 0x08, 0x10, 0x10, 0x10, 0x20, 0x00, 0x00,
                              /* 126 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                              /* 127 */ 0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00,
                              0 };


//------------------------------------------------------------------------------
// Local Functions
//
static void WriteChar( int x, int y, UINT8 ch);

extern void *InitDisplay(void);
//------------------------------------------------------------------------------
//
BOOL OEMLCDInit(BOOL fClear)
{
	int x, y;

	pwFrame = (PWORD)InitDisplay();
	pScreen = pwFrame + (ScrStatusHeight * ScrWidth);

	CursorX = CursorY = 0;

	if (fClear)
	{
		for (y = 0; y < TermHeight; y++)
		{
			for (x = 0; x < TermWidth; x++)
			{
				WriteChar( x, y, ' ');
			}
		}
	}

	return 1;
}


//------------------------------------------------------------------------------
//

VOID OEMLCDDeinit(VOID)
{
//
}

//------------------------------------------------------------------------------
//
VOID LCDWriteByte(char ch)
{

	switch (ch)
	{
	case '\n':
		CursorY++;
		break;
	case '\r':
		CursorX = 0;
		break;
	case '\b':
		CursorX = CursorX ? CursorX - 1 : 0;
		break;
	default:
		if (CursorX < TermWidth)
		{
			WriteChar( CursorX, CursorY, ch);
			if (ch != '\b')
				CursorX++;
		}
		break;
	}

	if (g_bLineWrap && (CursorX >= TermWidth))
	{
		CursorX = 0;
		CursorY++;
	}
	// just wrap to top of display
	if ( CursorY >= TermHeight)
	{
		UINT32 blocksize = (ScrWidth * PIXHEIGHT * 2) * (TermHeight - 1);
		// scroll up
		memcpy( pScreen,
		        pScreen + (ScrWidth*PIXHEIGHT),
		        blocksize);
		memset( pScreen + (blocksize >> 1), 0, (ScrWidth*PIXHEIGHT*2));

		CursorY--;
	}
}

//------------------------------------------------------------------------------
//
//  Function:  WriteChar
//
void WriteChar( int x, int y, UINT8 ch)
{
	UINT16 *pScr = pScreen + (x * PIXWIDTH) + (y * ScrWidth * PIXHEIGHT);
	UINT8 *pFont = fontdata;
	int i, v;
	UINT8 mask;
	UINT8 pix;

	if (ch < FIRSTCHAR || ch > LASTCHAR)
		ch = DEFAULTCHAR;

	ch -= FIRSTCHAR;

	pFont += ch * PIXHEIGHT;

	for ( i = 0; i < PIXHEIGHT; i++)
	{
		mask = 0x80;
		pix = *pFont++;
		for (v = 0; v < PIXWIDTH; v++)
		{
			if ((mask & pix) || !(g_wCharAttribute & DISP_ATTR_TRANSPARENT))
			{
				WORD wBColor, wFColor;
				if (g_wCharAttribute & DISP_ATTR_INVERT)
				{
					wBColor = g_wForeColor;
					wFColor = g_wBackColor;
				}
				else
				{
					wBColor = g_wBackColor;
					wFColor = g_wForeColor;
				}
				*pScr = (mask & pix) ? wFColor : wBColor;
			}

			pScr++;
			mask >>= 1;
		}
		pScr += (ScrWidth - PIXWIDTH);
	}
}

//------------------------------------------------------------------------------
//
//  Function:  OMAPLCDProgress
//
//  Update progress bar.
//
VOID LCDTermFillRect(WORD wX, WORD wY, INT nWidth, INT nHeight, WORD wColor)
{
	INT i, j;
	WORD *pwStart;

	// check parameters
	if (wX > ScrWidth || wY > ScrHeight || nWidth <= 0 || nHeight <= 0)
	{
		return ;
	}

	// do clipping
	if ((wX + nWidth) > ScrWidth)
	{
		nWidth = ScrWidth - wX;
	}

	if ((wY + nHeight) > ScrHeight)
	{
		nHeight = ScrHeight - wY;
	}

	pwStart = pwFrame + (wY * ScrWidth) + wX;
	for (i = 0 ; i < nHeight; i++)
	{
		for (j = 0; j < nWidth; j++)
		{
			pwStart[j] = wColor;
		}
		pwStart += ScrWidth;
	}

}

//------------------------------------------------------------------------------
//
//  Function:  OEMLCDProgress
//
//  Update progress bar.
//
VOID OEMLCDProgress(WORD wRgb, DWORD dwCurrent, DWORD dwMax)
{
	UINT16 *pFrame = pwFrame ;
	UINT16 i = 0, j = 0;
	UINT64 ui64Current = dwCurrent;
	UINT64 ui64Max = dwMax;

	if (dwMax == 0)
		return ;

	for (j = 0; j < 16; j++)
	{
		for (i = 0; i < (ui64Current*240) / ui64Max; i++)
			pFrame[j * 240 + i] = wRgb;
	}
}

//------------------------------------------------------------------------------
//  Output unicode string to lcd
//
VOID LCDWriteString(UINT16 *string)
{
	while (*string != L'\0')
	{
		LCDWriteByte((UINT8)*string++);
	}
}

//------------------------------------------------------------------------------
//
//  Function:  LCDTermPrintf
//
//  Output formatted unicode string to lcd
//
VOID LCDTermPrintf(LPCWSTR format, ...)
{
	va_list pArgList;
	WCHAR buffer[128];

	va_start(pArgList, format);
	NKwvsprintfW(buffer, format, pArgList, 128);
	va_end(pArgList);
	LCDWriteString(buffer);

}

//------------------------------------------------------------------------------
//
//  Function:  LCDTermvPrintf
//
//  Output formatted unicode string to lcd
//
VOID LCDTermvPrintf(LPCWSTR format, va_list pArgList)
{
	WCHAR buffer[128];

	NKwvsprintfW(buffer, format, pArgList, 128);
	LCDWriteString(buffer);
}
//------------------------------------------------------------------------------
//
//  Function:  SetBackColor
//
//
//
WORD SetBackColor(WORD bkColor)
{
	WORD wPrevColor = g_wBackColor;
	g_wBackColor = bkColor;
	return wPrevColor;
}

//------------------------------------------------------------------------------
//
//  Function:  SetForeColor
//
//
//
WORD SetForeColor(WORD foreColor)
{
	WORD wPrevColor = g_wForeColor;
	g_wForeColor = foreColor;
	return wPrevColor;
}

//------------------------------------------------------------------------------
//
//  Function:  SetCursorXY
//
//
//
BOOL SetCursorXY(WORD wX, WORD wY)
{
	BOOL fStatus = FALSE;
	if (wY <= TermHeight && wX <= TermWidth)
	{
		CursorX = wX;
		CursorY = wY;
		fStatus = TRUE;
	}
	return fStatus;
}

//------------------------------------------------------------------------------
//
//  Function:  GetCursorXY
//
//
//
VOID GetCursorXY(WORD *pwX, WORD *pwY)
{
	if (pwX)
		*pwX = CursorX;
	if (pwY)
		*pwY = CursorY;
}

//------------------------------------------------------------------------------
//
//  Function:  SetCharAttributes
//
//
//
WORD SetCharAttributes(WORD wAttrib)
{
	WORD wPrevAttrib = g_wCharAttribute;
	g_wCharAttribute = wAttrib;
	return wPrevAttrib;
}

//------------------------------------------------------------------------------
//
//  Function:  GetCharAttributes
//
//
//
WORD GetCharAttributes(VOID)
{
	return g_wCharAttribute;
}

__inline WORD rgb565(BYTE r, BYTE g, BYTE b)
{
	return (WORD) (((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3));
}


BOOL LCDTermShowSplash(unsigned char *pBitmap)
{
	UNALIGNED BITMAPFILEHEADER *pbmfh = (BITMAPFILEHEADER *)pBitmap;
	UNALIGNED BITMAPINFO *pbmi = (BITMAPINFO *)(pBitmap + sizeof(BITMAPFILEHEADER));
	UNALIGNED LPRGBQUAD ColorTable = (LPRGBQUAD)(pBitmap + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
	RGBQUAD rgb1, rgb2;

	WORD *pwDest;
	int x, y;

	// valid it's a bitmap file, we only support 4bit color
	if (!pbmfh ||
	        pbmfh->bfType != DIB_HEADER_MARKER || pbmi->bmiHeader.biSize != sizeof(BITMAPINFOHEADER) ||
	        pbmi->bmiHeader.biWidth != CX_SCREEN || pbmi->bmiHeader.biHeight != CY_SCREEN ||
	        pbmi->bmiHeader.biBitCount != 4)
	{
		return FALSE;
	}

	pBitmap += pbmfh->bfOffBits;
	pwDest = pwFrame + ((CY_SCREEN - 1) * CX_SCREEN);

	for (y = 0; y < CY_SCREEN; y++)
	{
		for (x = 0; x < CX_SCREEN; x += 2)
		{
			rgb1 = ColorTable[*pBitmap & 0xF];
			rgb2 = ColorTable[(*pBitmap & 0xF0) >> 4];
			pBitmap++;
			pwDest[x] = rgb565(rgb2.rgbRed, rgb2.rgbGreen, rgb2.rgbBlue);
			;
			pwDest[x + 1] = rgb565(rgb1.rgbRed, rgb1.rgbGreen, rgb1.rgbBlue);
			;
		}
		pwDest -= CX_SCREEN;
	}
	return TRUE;

}
//------------------------------------------------------------------------------------
VOID LCDBitblt(void * bmp, WORD height)
{
	UINT16 *pFrame = pwFrame;
#if 0

	UINT16 i = 0, j = 0;
#endif

#if 0
	// Set palette
	pPalette[0] = 0x4000;
	for (i = 1; i < 16; i++)
		pPalette[i] = 0;

	// Show picture here
	memset( pFrame, 0, 320*240*2);
#endif

#if 0
	// Show Picture Here
	for (j = 0; j < 57; j++)
	{
		for (i = 0; i < 240; i++)
			pFrame[j * 240 + i] = 0xFFE0;
	}
#endif
	memcpy(pFrame, bmp, CX_SCREEN*height*sizeof(UINT16));
}
